home *** CD-ROM | disk | FTP | other *** search
- /*
- Name: http.rexx
- Description: http downloader with resume support.
- Usage: rx http <url> [range]
- */
-
- signal on break_c
-
- l="rmh.library";if ~show("L",l) then;if ~addlib(l,0,-30) then exit
-
- prg=ProgramName("NOEXT")
- if ~Open("STDERR","CONSOLE:","W") then SDTERR="STDOUT"
-
- if AddLibrary("rexxsupport.library","rxsocket.library","rxlibnet.library")~=0 then
- call err "Can't find" result,1
-
- if ~RMH_ReadArgs("URL/A,RANGE/K") then do
- call PrintFault()
- exit
- end
-
- url=parm.0.value
- if upper(left(url,7))~="HTTP://" then url = "http://"url
- if ~ParseURI(url,"u") then call err "invalid url",1
-
- call info prg"/1.0 © alfie"
- call info "Host:" u.hostname
- call info "Port:" u.port
- call info "File:" u.query
-
- call info "Resolving host addr..."
- sin.addraddr=resolve(u.hostname)
- if sin.addraddr=-1 then call err "Host <"u.hostname"> not found",1
- sin.addrport=u.port
-
- sock=socket("INET","STREAM")
- if sock=-1 then call err "Can't create socket"
-
- call info "Connecting..."
- if connect(sock,"SIN")<0 then call err "Can't connect"
-
- fin="D0A"x
-
- if u.path="" then request="GET /"
- else request="GET" u.path
- if u.query~="" then request= request || "?"u.query
- request = request "HTTP/1.0"fin
- request = request || "User-agent: http.rexx" || fin
- request = request || "Host:" u.HostInfo || fin
- if parm.1.flag then request = request"Range: bytes="parm.1.value||fin
- if u.user~="" & u.password~="" then do
- call encodeb64(u.user":"u.password,auth,"string var")
- request = request || "Authorization: Basic" auth || fin
- call info "User:" u.user
- call info "Pass:" u.password
- call info "Auth:" auth
- end
- request = request||fin
-
- call info "Sending request..."
- if send(sock,request)<0 then call err "Error sending"
-
- call info "Receiving results..."
- sel.read.0=sock
- buf=""
- p=0
- do while p=0
-
- res = WaitSelect("sel")
- if res<0 then call err "Error in select()"
- if ~sel.0.read then iterate /* no read event on s */
-
- res=recv(sock,"B",1024)
- if res=0 then call err "Link closed",1
- do while p=0 & res>0
- buf=buf||b
- res=recv(sock,"B",1024)
- p=pos("0D0A"x,buf)
- end
- if res<0 then call err "Error reading"
- buf=buf||b
- end
-
- if p=1 then call err "Empty answer",1
- parse var buf head "0D0A"x buf
- if words(head)<3 then call err "Bad answer",1
- parse var head h " " code " " reasone
-
- call info "----------------"
- call info head
- do k=0 while line~=""
- parse var buf line "0D0A"x buf
- if line="" then iterate
- call info line
- end
- call info "----------------"
-
- if code~=200 & code~=206 then call err "Error from server: <"code reasone">" ,1
-
- call info "Receiving file..."
-
- do forever
-
- call WriteCH("STDOUT",buf)
-
- res = WaitSelect("sel")
- if res<0 then call err "Error in select()"
- if ~sel.0.read then iterate /* no read event on s */
-
- res=recv(sock,"BUF",1024)
- if res=0 then leave
- do while res>0
- call WriteCH("STDOUT",buf)
- res=recv(sock,"BUF",1024)
- end
- /*if res<0 & errno()~=35 then call err "Error reading"*/
- if res<0 then call err "Error reading"
- end
- call info "Done."
- exit
-
- err:
- parse arg msg,ntdoerr
- if ntdoerr~=1 then msg=msg "("errorstring(errno())")"
- call info(msg".")
- exit
-
- info:
- parse arg msg
- call writeln(STDERR,msg)
- return
-
- break_c:
- call info "user break."
- exit
-